#include "choosezone.h"
#include "ui_choosezone.h"

#include "timezonewidget.h"
#include "locale/Config.h"

#include <QComboBox>
#include <QtDBus/QDBusInterface>
#include <QtDBus/QDBusReply>
#include <QtDBus/QDBusConnection>

ChooseZone::ChooseZone(QWidget *parent) :
    Base(parent),
    ui(new Ui::ChooseZone),
    m_config(new Config(this))
{
    ui->setupUi(this);

    // default shanghai
    //m_config->setCurrentLocation();

    qInfo() << "---zonesModel: " << m_config->zonesModel();
    m_tzWidget = new TimeZoneWidget( m_config->zonesModel(),ui->map_wgt);
    m_tzWidget->show();

    Locale::RegionsModel* regions = m_config->regionModel();
    Locale::RegionalZonesModel* zones = m_config->regionalZonesModel();
    auto* location = m_config->currentLocation();
    zones->setRegion( location->region() );

    ui->region_Cbx->setModel( regions );
    ui->zone_Cbx->setModel( zones );
    m_tzWidget->setCurrentLocation( location );
    locationChanged( location );  // doesn't inform TZ widget

    connect( m_config, &Config::currentLocationChanged, m_tzWidget, &TimeZoneWidget::setCurrentLocation ); // config -> map
    connect( m_config, &Config::currentLocationChanged, this, &ChooseZone::locationChanged );   // config -> zone
    connect( m_tzWidget,
             &TimeZoneWidget::locationChanged,
             m_config,
             QOverload< const Locale::TimeZoneData* >::of( &Config::setCurrentLocation ) ); // map -> config
    connect( ui->region_Cbx, QOverload< int >::of( &QComboBox::currentIndexChanged ), this, &ChooseZone::regionChanged ); // region -> config, resion -> zone
    connect(ui->zone_Cbx, QOverload< int >::of( &QComboBox::currentIndexChanged ), this, &ChooseZone::zoneChanged ); // zone -> config

    m_timezone = "Asia/Shanghai";
    int index = ui->region_Cbx->findData("Asia");
    if ( index < 0 )
    {
        return;
    }
    ui->region_Cbx->setCurrentIndex(index);
    index = ui->zone_Cbx->findData("Shanghai");
    if ( index < 0 )
    {
        return;
    }
    ui->zone_Cbx->setCurrentIndex( index );
}

ChooseZone::~ChooseZone()
{
    delete ui;
}

void ChooseZone::start()
{
    ui->zone_Cbx->setFocus();
}

bool ChooseZone::nextStep()
{
    QDBusInterface timeDatedIface("org.freedesktop.timedate1","/org/freedesktop/timedate1", "org.freedesktop.timedate1",
                                  QDBusConnection::systemBus());
    QDBusReply<bool> reply = timeDatedIface.callWithArgumentList(QDBus::AutoDetect, QStringLiteral("SetTimezone"), QList<QVariant>() << m_timezone << false);
    qInfo() << " set timezone " << timezone << ", result: " << reply.value() << ", error: " << reply.error();

    return true;
}

QList<QPair<QString, QString> > ChooseZone::getData()
{
    return QList<QPair<QString, QString> >() << QPair("locale", m_timezone);
}

void ChooseZone::locationChanged(const Locale::TimeZoneData *location)
{
    if ( !location )
    {
        return;
    }
    m_blockTzWidgetSet = true;

    // Set region index
    int index = ui->region_Cbx->findData( location->region() );
    if ( index < 0 )
    {
        return;
    }

    ui->region_Cbx->setCurrentIndex( index );

    // Set zone index
    index = ui->zone_Cbx->findData( location->zone() );
    if ( index < 0 )
    {
        return;
    }

    ui->zone_Cbx->setCurrentIndex( index );


    m_timezone = ui->region_Cbx->currentData().toString() + "/" + ui->zone_Cbx->currentData().toString();
    m_blockTzWidgetSet = false;
}

void ChooseZone::regionChanged(int currentIndex)
{
    using namespace Locale;
    QString selectedRegion = ui->region_Cbx->itemData( currentIndex ).toString();
    {
        QSignalBlocker z( ui->zone_Cbx );
        m_config->regionalZonesModel()->setRegion( selectedRegion );
    }
    ui->zone_Cbx->currentIndexChanged( 0 );
    m_timezone = ui->region_Cbx->currentData().toString() + "/" + ui->zone_Cbx->currentData().toString();
}

void ChooseZone::zoneChanged(int currentIndex)
{
    if ( !m_blockTzWidgetSet )
    {
        m_config->setCurrentLocation( ui->region_Cbx->currentData().toString(),
                                      ui->zone_Cbx->itemData( currentIndex ).toString() );
    }
}
